#include "datagram_builder.h"

#include "logger.h"

const std::string CDatagramBuilder::sIniSectionName("DATAGRAM_BUILDER");

CDatagramBuilder::CDatagramBuilder(CPropertiesReader* pConfig, IStegIO* pStegIO) :
	mConfig(pConfig),
	mStegIO(pStegIO),
	mByteBuffer(NULL),
	mByteBufferSize(0)
{

}

CDatagramBuilder::~CDatagramBuilder()
{
	getByteBuffer(0);
}

NPacketSource::EPayloadInfo CDatagramBuilder::getPacket(void*& pPacket, unsigned int& pPacketLength, unsigned int pMaxLength)
{
	if (!pMaxLength) {
		return NPacketSource::PAYLOAD_ERROR;
	}

	unsigned char* lPacketBuffer(getByteBuffer(pMaxLength));
	NStegIO::EReadState lState;
	for (pPacketLength = 0; pPacketLength < pMaxLength; pPacketLength++) {
		lState = mStegIO->read(lPacketBuffer[pPacketLength]);
		if (lState != NStegIO::READ_STATE_DATA) {
			break;
		}
	}

	printl(0, __FILE__, "Generated packet, payload length: %u", pPacketLength);

	pPacket = lPacketBuffer;
	switch (lState) {
		case NStegIO::READ_STATE_ERROR:
			return NPacketSource::PAYLOAD_ERROR;
		case NStegIO::READ_STATE_EOF:
			return NPacketSource::PAYLOAD_EOF;
		case NStegIO::READ_STATE_DATA:
		case NStegIO::READ_STATE_NODATA:
			return pPacketLength ? NPacketSource::PAYLOAD_DATA : NPacketSource::PAYLOAD_NO_DATA;
	}

	return NPacketSource::PAYLOAD_ERROR; // should not be possible
}

void CDatagramBuilder::putPacket(void* pPacket, unsigned int pPacketLength)
{
	if (!pPacket) {
		return;
	}

	for (unsigned int i = 0; i < pPacketLength; i++) {
		mStegIO->write(static_cast<unsigned char*>(pPacket)[i]);
	}
}

unsigned char* CDatagramBuilder::getByteBuffer(unsigned int pSize)
{
	if (pSize == 0) {
		delete[] mByteBuffer;
		mByteBuffer = NULL;
		mByteBufferSize = 0;
	}
	else if (pSize > mByteBufferSize) {
		delete[] mByteBuffer;
		mByteBuffer = new unsigned char[pSize];
		mByteBufferSize = pSize;
	}

	return mByteBuffer;
}

